﻿
using Xacml.Core;
using System;
using System.Xml;

namespace Xacml.Core.Policy
{
  public class TargetElementReadWrite : XacmlElement
  {
    private ResourcesElementReadWrite _resources;
    private SubjectsElementReadWrite _subjects;
    private ActionsElementReadWrite _actions;
    private EnvironmentsElementReadWrite _environments;

    public virtual ResourcesElementReadWrite Resources
    {
      get
      {
        return this._resources;
      }
      set
      {
        this._resources = value;
      }
    }

    public virtual SubjectsElementReadWrite Subjects
    {
      get
      {
        return this._subjects;
      }
      set
      {
        this._subjects = value;
      }
    }

    public virtual ActionsElementReadWrite Actions
    {
      get
      {
        return this._actions;
      }
      set
      {
        this._actions = value;
      }
    }

    public virtual EnvironmentsElementReadWrite Environments
    {
      get
      {
        return this._environments;
      }
      set
      {
        this._environments = value;
      }
    }

    public override bool IsReadOnly
    {
      get
      {
        return false;
      }
    }

    public TargetElementReadWrite(ResourcesElementReadWrite resources, SubjectsElementReadWrite subjects, ActionsElementReadWrite actions, EnvironmentsElementReadWrite environments, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      this._resources = resources;
      this._subjects = subjects;
      this._actions = actions;
      this._environments = environments;
    }

    public TargetElementReadWrite(XmlReader reader, XacmlVersion schemaVersion)
      : base(XacmlSchema.Policy, schemaVersion)
    {
      if (reader.LocalName == "Target" && this.ValidateSchema(reader, schemaVersion))
      {
        if (!reader.IsEmptyElement)
        {
          while (reader.Read())
          {
            switch (reader.LocalName)
            {
              case "Subjects":
                this._subjects = new SubjectsElementReadWrite(reader, schemaVersion);
                break;
              case "Resources":
                this._resources = new ResourcesElementReadWrite(reader, schemaVersion);
                break;
              case "Actions":
                this._actions = new ActionsElementReadWrite(reader, schemaVersion);
                break;
              case "Environments":
                this._environments = new EnvironmentsElementReadWrite(reader, schemaVersion);
                break;
            }
            if (reader.LocalName == "Target" && reader.NodeType == XmlNodeType.EndElement)
              break;
          }
        }
        if (schemaVersion != XacmlVersion.Version20)
          return;
        if (this._subjects == null)
          this._subjects = new SubjectsElementReadWrite(true, new TargetItemCollectionReadWrite(), schemaVersion);
        if (this._resources == null)
          this._resources = new ResourcesElementReadWrite(true, new TargetItemCollectionReadWrite(), schemaVersion);
        if (this._actions != null)
          return;
        this._actions = new ActionsElementReadWrite(true, new TargetItemCollectionReadWrite(), schemaVersion);
      }
      else
        throw new Exception(Resource.ResourceManager[Resource.MessageKey.exc_invalid_node_name, new object[1]
        {
          (object) reader.LocalName
        }]);
    }

    public void WriteDocument(XmlWriter writer)
    {
      writer.WriteStartElement("Target");
      switch (this.SchemaVersion)
      {
        case XacmlVersion.Version10:
        case XacmlVersion.Version11:
          if (this._subjects != null)
            this._subjects.WriteDocument(writer);
          if (this._resources != null)
            this._resources.WriteDocument(writer);
          if (this._actions != null)
            this._actions.WriteDocument(writer);
          if (this._environments != null)
          {
            this._environments.WriteDocument(writer);
            break;
          }
          break;
        case XacmlVersion.Version20:
          if (this._subjects != null && !this._subjects.IsAny)
            this._subjects.WriteDocument(writer);
          if (this._resources != null && !this._resources.IsAny)
            this._resources.WriteDocument(writer);
          if (this._actions != null && !this._actions.IsAny)
            this._actions.WriteDocument(writer);
          if (this._environments != null && !this._environments.IsAny)
          {
            this._environments.WriteDocument(writer);
            break;
          }
          break;
      }
      writer.WriteEndElement();
    }
  }
}
